package ru.classbase.dbdumper

import org.springframework.boot.context.properties.ConfigurationProperties
import ru.classbase.dbdumper.model.CompressionType
import ru.classbase.dbdumper.model.CompressionType.ZIP
import ru.classbase.dbdumper.model.OutputFormat
import ru.classbase.dbdumper.model.OutputFormat.POSTGRES_SQL_INSERT
import ru.classbase.dbdumper.model.StorageType
import java.nio.charset.Charset
import java.nio.charset.StandardCharsets
import java.nio.file.Path
import java.nio.file.Paths


@ConfigurationProperties(prefix = "app")
data class AppProperties(
    val workerCount: Int = 4,
    val rowsPerInsert: Int = 4,
    val compressionType: CompressionType = ZIP,
    /**
     * Таймаут ожидания получения блокировок таблиц
     */
    val lockTimeout: Int = 60,
    val outputFormat: OutputFormat = POSTGRES_SQL_INSERT,
    val storageType: StorageType = StorageType.DIRECTORY,
    val outputEncoding: Charset = StandardCharsets.UTF_8,
    val schemas: List<SchemaProperties> = listOf(),
    val dateFormat: String? = null,
    val dateTimeFormat: String? = null,
    val csv: CsvProperties = CsvProperties(),
    val gdrive: GoogleDriveProperties = GoogleDriveProperties(),
    val directory: DirectoryProperties = DirectoryProperties()
)

data class DirectoryProperties(
    val outputDir: String = System.getProperty("user.dir")
)

data class GoogleDriveProperties(
    val credentialsFilePath: Path = Paths.get("dbdump-service-account.json"),
    val folderId: String? = null,
    val applicationName: String = "DB Dumper"
)

data class SchemaProperties(
    val schemaName: String,
    val includeTables: List<Regex> = listOf(),
    val excludeTables: List<Regex> = listOf(),
)

data class CsvProperties(
    val lineEnd: String = "\n",
    val quoteChar: Char = '"',
    val separator: Char = ',',
    val escapeChar: Char = '\\',
    val includeColumnNames: Boolean = true,
)

fun validateProperties(props: AppProperties) {
    check(props.workerCount in 1..16) { "Количество воркеров должно быть в диапазоне от 1 до 16" }
    check(props.rowsPerInsert in 1..1000) { "Количество значений (VALUES) в выражении INSERT должно в диапазоне от 1 до 1000" }
    check(props.lockTimeout in 1..3600) { "Таймаут ожидания блокировки таблицы должен быть в диапазоне от 1 до 3600 секунд" }
}